package com.brainhealth.utils;

import cn.hutool.core.util.ClassUtil;
import com.alibaba.fastjson2.JSON;
import com.brainhealth.common.config.RuoYiConfig;
import com.brainhealth.common.constant.CacheConstants;
import com.brainhealth.common.core.domain.TreeSelect;
import com.brainhealth.common.core.redis.RedisCache;
import com.brainhealth.common.utils.StringUtils;
import com.brainhealth.common.utils.reflect.ReflectUtils;
import com.brainhealth.common.utils.spring.SpringUtils;
import com.brainhealth.customer.domain.Customer;
import com.brainhealth.customer.domain.CustomerExercise;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.nio.file.Path;
import java.text.DecimalFormat;
import java.util.*;

public class CommonUtils
{
    private static Logger logger = LoggerFactory.getLogger(CommonUtils.class);

    /**
     * 使用请求头中的token获取redis中的会员信息
     * @param request
     * @return
     */
    public static Customer getCustomerByRequest(HttpServletRequest request)
    {
        String token = request.getHeader("tokens");
        if (StringUtils.isEmpty(token))
        {
            throw new RuntimeException("token不能为空");
        }
        RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
        Collection<String> collection = redisCache.keys(CacheConstants.CUSTOMER_TOKEN + "*" + ":" + token);
        if (collection.size() > 0)
        {
            Iterator iterator = collection.iterator();
            while (iterator.hasNext())
            {
                String customerToken = iterator.next().toString();
                if (customerToken.contains(token))
                {
                    String jsonString = redisCache.getCacheObject(customerToken);
                    Customer customer = JSON.parseObject(jsonString, Customer.class);
                    if (customer != null)
                    {
                        return customer;
                    }
                }
            }
            throw new RuntimeException("登录已失效！请重新登录！");
        } else
        {
            throw new RuntimeException("登录已失效！请重新登录！");
        }
    }

    /**
     * 按训练次数分组会员训练记录
     * @param lstCustomerExercise
     * @return
     */
    public static Map<Long, List<CustomerExercise>> getCountSortMap(List<CustomerExercise> lstCustomerExercise)
    {
        //把会员的训练记录分成每次一组来显示
        Map<Long, List<CustomerExercise>> mCustomerExercise = new HashMap<>();
        for (CustomerExercise customerExercise : lstCustomerExercise)
        {
            if (!mCustomerExercise.containsKey(customerExercise.getCountSort()))
            {
                List<CustomerExercise> lstGroupExercise = new ArrayList<>();
                lstGroupExercise.add(customerExercise);
                mCustomerExercise.put(customerExercise.getCountSort(), lstGroupExercise);
            } else
            {
                mCustomerExercise.get(customerExercise.getCountSort()).add(customerExercise);
            }
        }
        return mCustomerExercise;
    }

    /**
     * 把各种数据分组处理
     * @param lstData
     * @param <T>
     * @return
     */
    public static <T> List<List<T>> getGroupList(int listSize, List<T> lstData)
    {
        List<List<T>> lstGroupScore = new ArrayList<>();
        for (int i = 0; i < listSize; i++)
        {
            lstGroupScore.add(new ArrayList<>());
        }
        for (T t : lstData)
        {
            Long pos = null;
            try
            {
                Method method = t.getClass().getMethod("getCountSort");
                Long countSort = (Long) method.invoke(t);
                Long nowPos = countSort / 7;
                if (countSort % 7 == 0)
                {
                    nowPos = nowPos - 1;
                }
                pos = nowPos;
            } catch (NoSuchMethodException e)
            {
                e.printStackTrace();
            } catch (IllegalAccessException e)
            {
                e.printStackTrace();
            } catch (InvocationTargetException e)
            {
                e.printStackTrace();
            }
            if (pos.intValue() >= lstGroupScore.size())
            {
                lstGroupScore.get(lstGroupScore.size() - 1).add(t);
            } else
            {
                lstGroupScore.get(pos.intValue()).add(t);
            }
        }
        return lstGroupScore;
    }

    /**
     * 两个整数相除变成百分比
     * b 是除数
     * a 是被除数
     */
    public static int getPercentValue(int a, int b)
    {
        DecimalFormat df = new DecimalFormat("0.00");
        String result = df.format(((double) b / a) * 100);
        return Integer.valueOf(result.substring(0,result.indexOf(".")));
    }


    /**
     * 获取用户选择的机构树形结构
     * @param node 父节点
     * @param lstAllData    所有数据
     * @param idMethod      树形结构Key Id方法
     * @param nameMethod    树形结构名称方法
     * @param parentMethond 树形结构父级ID方法
     * @param <T>
     */
    public static <T> void getTreeSelectChildren(TreeSelect node, List<T> lstAllData, String idMethod, String nameMethod, String parentMethond)
    {
        try
        {
            List<T> lstChildren = new ArrayList<>();
            for (T nodeData : lstAllData)
            {
                Method method = nodeData.getClass().getMethod(parentMethond);
                Long parentId = (Long) method.invoke(nodeData);
                if (parentId.toString().equals(node.getId().toString()))
                {
                    lstChildren.add(nodeData);
                }
            }
            if (lstChildren.size() > 0)
            {
                for (T childData : lstChildren)
                {
                    TreeSelect childNode = new TreeSelect();
                    Method methodId = childData.getClass().getMethod(idMethod);
                    childNode.setId((Long) methodId.invoke(childData));
                    Method methodName = childData.getClass().getMethod(nameMethod);
                    childNode.setLabel(methodName.invoke(childData).toString());
                    node.getChildren().add(childNode);
                }
            }
        } catch (Exception e)
        {
            logger.error("数据转换异常", e);
        }
        for (TreeSelect child : node.getChildren())
        {
            getTreeSelectChildren(child, lstAllData, idMethod, nameMethod, parentMethond);
        }
    }

    /**
     * 导出文件响应流
     * @param response
     */
    public static void exportExcel(HttpServletResponse response, String fileName)
    {
        ServletOutputStream out = null;
        File file = new File(fileName);
        try
        {
            out = response.getOutputStream();
            /** 导出excel文件流 */
            response.setHeader("content-Type", "application/vnd.ms-excel");
//            response.setHeader("content-Type", "application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("excelFile", "UTF-8"));
            response.setCharacterEncoding("UTF-8");
            /** 导出pdf文件流 */
//            response.setCharacterEncoding("UTF-8");
//            response.setContentType("application/pdf");
//            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "inline; filename="+ URLEncoder.encode("下载简历","UTF-8"));
            FileInputStream inputStream = new FileInputStream(file);
            // 读取文件流
            int len = 0;
            byte[] buffer = new byte[1024 * 10];
            while ((len = inputStream.read(buffer)) != -1)
            {
                out.write(buffer, 0, len);
            }
            out.close();
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
